# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2005-2006 CamptoCamp
# Copyright (c) 2006-2010 OpenERP S.A
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly advised to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
##############################################################################
import time, os
from openerp.osv import osv, fields
from openerp.tools.translate import _
from openerp.report import report_sxw
import locale
locale.setlocale(locale.LC_ALL, '')

class bank_statement_reconcile_report(report_sxw.rml_parse):
    _name = 'bank.statement.reconcile.report'

    def _search_data(self, cr, uid, ids, data_obj, val_data, filter_selection, default_from, default_to, input_from, input_to, selection_ids, context=None):
        data_header = ''
        data_ids = []

        if context is None:
            context = {}
        
        if filter_selection == 'all_vall':
            data_ids = data_obj.search(cr, uid, val_data, order='id ASC')
        if filter_selection == 'def':
            data_found = False
            if default_from and data_obj.browse(cr, uid, default_from) and data_obj.browse(cr, uid, default_from).name:
                default_from_header = data_obj.browse(cr, uid, default_from).name
                data_found = True
                val_data.append(('name', '>=', default_from_header))
            if default_to and data_obj.browse(cr, uid, default_to) and data_obj.browse(cr, uid, default_to).name:
                default_to_header = data_obj.browse(cr, uid, default_to).name
                data_found = True
                val_data.append(('name', '<=', default_to_header))
            if data_found:
                data_header = '"' + default_from_header + '" - "' + default_to_header + '"'
                data_ids = data_obj.search(cr, uid, val_data, order='id ASC')
        if filter_selection == 'input':
            data_found = False
            if input_from:
                data_ids_from = data_obj.search(cr, uid, [('name','=ilike', input_from + '%')], order="name", limit=1)
                if data_ids_from:
                    input_from_name = data_obj.browse(cr, uid, data_ids_from[0]).name
                    data_found = True
                    val_data.append(('name', '>=', input_from_name))
            if input_to:
                data_ids_to = data_obj.search(cr, uid, [('name','=ilike', input_to + '%')], order="name desc", limit=1)
                if data_ids_to:
                    input_to_name = data_obj.browse(cr, uid, data_ids_to[0]).name
                    data_found = True
                    val_data.append(('name', '<=', input_to_name))
            data_header = '"' + input_from + '" - "' + input_to + '"'
            if data_found:
                data_ids = data_obj.search(cr, uid, val_data, order='id ASC')
        if filter_selection == 'selection':
            if selection_ids:
                sel_ids = ''
                for sel in  data_obj.browse(cr, uid, selection_ids):
                    sel_ids += ('"%s",')%(sel.name,)

                data_header = '[' + sel_ids +']'
                data_ids = selection_ids
                
        return data_header, data_ids
    
    def set_context(self, objects, data, ids, context=None):
        new_ids = ids
        
        if context is None:
            context = {}
            
        self.sortby_ids = data['form']['sortby_ids'] or False
        self.target_move = data['form']['target_move'] or False
        self.output_account_header, self.account_ids = self._search_data(self.cr, self.uid, ids, self.pool.get('account.account'),
                                                                                      [],
                                                                                      data['form']['account_selection'],
                                                                                      data['form']['account_default_from'] and data['form']['account_default_from'][0] or False,
                                                                                      data['form']['account_default_to'] and data['form']['account_default_to'][0] or False,
                                                                                      data['form']['account_input_from'] or False,
                                                                                      data['form']['account_input_to'] or False,
                                                                                      data['form']['account_name_ids'] or False,
                                                                                      context=context)

        self.output_journal_header, self.journal_ids = self._search_data(self.cr, self.uid, ids, self.pool.get('account.journal'),
                                                                                      [],
                                                                                      data['form']['journal_selection'],
                                                                                      data['form']['journal_default_from'] and data['form']['journal_default_from'][0] or False,
                                                                                      data['form']['journal_default_to'] and data['form']['journal_default_to'][0] or False,
                                                                                      data['form']['journal_input_from'] or False,
                                                                                      data['form']['journal_input_to'] or False,
                                                                                      data['form']['journal_name_ids'] or False,
                                                                                      context=context)
        
        self.output_currency_header, self.currency_ids = self._search_data(self.cr, self.uid, ids, self.pool.get('res.currency'),
                                                                                      [],
                                                                                      data['form']['currency_selection'],
                                                                                      data['form']['currency_default_from'] and data['form']['currency_default_from'][0] or False,
                                                                                      data['form']['currency_default_to'] and data['form']['currency_default_to'][0] or False,
                                                                                      data['form']['currency_input_from'] or False,
                                                                                      data['form']['currency_input_to'] or False,
                                                                                      data['form']['currency_name_ids'] or False,
                                                                                      context=context)
        
        return super(bank_statement_reconcile_report, self).set_context(objects, data, new_ids)

    def __init__(self, cr, uid, name, context=None):
        super(bank_statement_reconcile_report, self).__init__(cr, uid, name, context=context)
        self.localcontext.update({
            'time': time,
            'locale': locale,
            'get_printed_date' : self._get_printed_date,
            'get_printed_by': self._get_printed_by,
            'get_account_accuracy': self._get_account_accuracy,
            'get_exrate_accuracy': self._get_exrate_accuracy,
            'get_output_journal_header': self._get_output_journal_header,
            'get_output_account_header': self._get_output_account_header,
            'get_output_currency_header': self._get_output_currency_header,
            'get_output_sortby_header': self._get_output_sortby_header,
            'get_lines': self._get_lines,
            'get_target_move': self._get_target_move,
            })
    
    def _get_account_accuracy(self):
        dp = 2
        dp_obj = self.pool.get('decimal.precision')
        dp_ids = dp_obj.search(self.cr, self.uid, [('name','=','Account')])
        if dp_ids :
            dp_id = dp_obj.browse(self.cr, self.uid, dp_ids[0])
            dp = dp_id.digits
        return dp  
    
    def _get_exrate_accuracy(self):
        dp = 2
        dp_obj = self.pool.get('decimal.precision')
        dp_ids = dp_obj.search(self.cr, self.uid, [('name','=','Payment Term')])
        if dp_ids :
            dp_id = dp_obj.browse(self.cr, self.uid, dp_ids[0])
            dp = dp_id.digits
        return dp  
    
    def _get_printed_date(self):
        header = ''
        user_obj = self.pool.get('res.users')
        user_ids = user_obj.search(self.cr, self.uid, [('id','=',self.uid)])
        if user_ids :
            tz = user_obj.browse(self.cr, self.uid, user_ids[0])
            tz_name = tz.tz
        os.environ['TZ'] = tz_name
        time.tzset()
        header = 'Printed date : ' + time.strftime("%Y/%m/%d") + '  Time : '+ time.strftime("%H:%M:%S")
         
        return header
    
    def _get_printed_by(self):
        header =''
        user_obj = self.pool.get('res.users')
        user_ids = user_obj.search(self.cr, self.uid, [('id','=',self.uid)])
        if user_ids :
            user_id = user_obj.browse(self.cr, self.uid, user_ids[0])
            user_name = user_id.name

        header = 'Printed by : ' + user_name
        
        return header
    
    def _get_output_journal_header(self):
        header = ''
        if self.output_journal_header:
            header = 'Journal : ' + self.output_journal_header
         
        return header
    
    def _get_output_account_header(self):
        header = ''
        if self.output_account_header:
            header = 'Account : ' + self.output_account_header
         
        return header
    
    def _get_output_currency_header(self):
        header = ''
        if self.output_currency_header:
            header = 'Currency : ' + self.output_currency_header
         
        return header
    
    def _get_target_move(self):
        header = False
        if self.target_move == 'posted': 
                header = 'Target Move : All Posted Entries'  
        elif self.target_move == 'all': 
                header = 'Target Move : All Entries'
        return header
    
    def _get_output_sortby_header(self):
        header = output_sortby_header = ''
        result = []
        
        if self.sortby_ids:
            sortby_ids = self.pool.get('param.bank.statement.reconcile.report.sortby').search(self.cr, self.uid, [('id', 'in', self.sortby_ids)], order='seq desc')
        
        if sortby_ids:
            for item in self.pool.get('param.bank.statement.reconcile.report.sortby').browse(self.cr, self.uid, sortby_ids):
                result.append({
                        'seq' : item['seq'],
                        'sort_by' : item['sort_by'],
                        })
            result = result and sorted(result, key=lambda val_res: val_res['seq']) or []               
            
            for rs in result:
                sort_name = ''
                if rs['sort_by'] == 'journal_name':
                    sort_name = 'Journal'
                elif rs['sort_by'] == 'account_name':
                    sort_name = 'Account'
                elif rs['sort_by'] == 'curr_name':
                    sort_name = 'Currency'
                
                output_sortby_header += ('"%s",')%(sort_name,)
            header = 'Sort By : ' + output_sortby_header

        return header
    
    def _get_lines(self):
        cr  = self.cr
        uid = self.uid
        
        user_obj = self.pool.get('res.users')
        aml_obj = self.pool.get('account.move.line')
        sortby_obj = self.pool.get('param.bank.statement.reconcile.report.sortby')

        results        = []
        val_bank_recon = []
        
        target_move = self.target_move 
        journal_ids = self.journal_ids
        account_ids = self.account_ids
        currency_ids = self.currency_ids
        sortby_ids = self.sortby_ids

        output_sortby_header = ''
        
        val_bank_recon.append(('checked_by_user','=',True))
        val_bank_recon.append(('account_id.bank_account','=',True))
        
        if journal_ids:
            val_bank_recon.append(('journal_id','in',journal_ids))
        if account_ids:
            val_bank_recon.append(('account_id','in',account_ids))
        if currency_ids:
            val_bank_recon.append(('currency_id','in',currency_ids))
        
        bank_recon_sortby_ids = []
        if sortby_ids:
            bank_recon_sortby_ids = sortby_obj.search(cr, uid, [('id', 'in', self.sortby_ids)], order='seq desc')
         
        if target_move == 'posted':  
            val_bank_recon.append(('move_id.state','=','posted'))
            
        bank_reconcile_ids = aml_obj.search(cr, uid, val_bank_recon)
        if bank_reconcile_ids:
            br_ids = []
            
            for br in aml_obj.browse(cr, uid, bank_reconcile_ids):
                br_ids.append({
                    'journal_name' : br.journal_id.name,
                    'ref' : br.ref,
                    'account_name' : br.account_id.name,
                    'debit' : br.debit,
                    'credit' : br.credit,
                    'curr_name' : br.currency_id.name,
                    'amt_orig' : br.amount_original,
                    'exrate' : br.exrate,
                    'checked_by' : br.bank_check_by.name
                })
            if bank_recon_sortby_ids:
                for bank_recon_sortby in sortby_obj.browse(cr, uid, sortby_ids):
                    br_ids = br_ids and sorted(br_ids, key=lambda val_res: val_res[bank_recon_sortby.sort_by]) or []               
            else:
                br_ids = br_ids and sorted(br_ids, key=lambda val_res: val_res['curr_name']) or []               
                br_ids = br_ids and sorted(br_ids, key=lambda val_res: val_res['account_name']) or []
                br_ids = br_ids and sorted(br_ids, key=lambda val_res: val_res['journal_name']) or []
            
            for br_result in br_ids:
                results.append({
                    'journal_name' : br_result['journal_name'] or '',
                    'ref' : br_result['ref'] or '',
                    'account_name' : br_result['account_name'] or '',
                    'debit' : br_result['debit'] or 0.00,
                    'credit' : br_result['credit'] or 0.00,
                    'curr_name' : br_result['curr_name'] or '',
                    'amt_orig' : br_result['amt_orig'] or 0.00,
                    'exrate' : br_result['exrate'] or 0.000000,
                    'checked_by' : br_result['checked_by'] or '',
                })

        return results
        
report_sxw.report_sxw('report.bank.statement.reconcile.report_landscape', 'param.bank.statement.reconcile.report',
    'addons/batam_fast_module/account/report/bank_statement_reconcile_report.rml', parser=bank_statement_reconcile_report, header=False)
